const dotnetApiIndexUrl = "https://docs.microsoft.com/zh-cn/dotnet/api/";
const dotnetFamilyTreesUrl =
    "https://docs.microsoft.com/_api/familyTrees/byPlatform/dotnet";
const namespaceUrl =
    "https://docs.microsoft.com/api/apibrowser/dotnet/namespaces";

import * as fs from "fs";
import * as https from "https";
import * as path from "path";
import {
    Product,
    ProductFamily,
    ApiItem,
    Package,
    DocIndex,
} from "./types/api-browser";

const getDotnetFamilyTrees = (): Promise<Array<ProductFamily>> => {
    return new Promise((resolve, reject) => {
        https
            .get(dotnetFamilyTreesUrl, (resp) => {
                if (resp.statusCode !== 200) {
                    return reject(
                        new Error("返回状态码 --- " + resp.statusCode)
                    );
                }

                resp.setEncoding("utf-8");

                let rawData = "";
                resp.on("data", (chunk) => (rawData += chunk));
                resp.on("end", () => {
                    // console.log(rawData);

                    let dataPath = path.join(__dirname, "data");
                    if (!fs.existsSync(dataPath)) {
                        console.log("create", dataPath);
                        fs.mkdirSync(dataPath);
                    }

                    fs.writeFileSync(
                        path.join(
                            __dirname,
                            "data",
                            "dotnet-family-trees.json"
                        ),
                        rawData
                    );

                    resolve(JSON.parse(rawData));
                });
            })
            .on("error", (e) => {
                reject(e);
            });
    });
};

const getProductPackageNamespaces = (
    productPackage: Package
): Promise<Array<ApiItem>> => {
    let targetUrl = `${namespaceUrl}?moniker=${productPackage.monikerName}&api-version=0.2&locale=zh-cn`;

    console.log("target url", targetUrl);

    return new Promise((resolve, reject) => {
        https
            .get(targetUrl, (resp) => {
                if (resp.statusCode !== 200) {
                    return reject(
                        new Error("返回状态码 --- " + resp.statusCode)
                    );
                }

                resp.setEncoding("utf-8");

                let rawData = "";
                resp.on("data", (chunk) => (rawData += chunk));
                resp.on("end", () => {
                    resolve(JSON.parse(rawData));
                });
            })
            .on("error", (e) => {
                reject(e);
            });
    });
};

const main = async () => {
    let allFamilies = await getDotnetFamilyTrees();

    let namespacesIndexes = [];

    let dataPath = path.join(__dirname, "data");

    if (!fs.existsSync(dataPath)) {
        fs.mkdirSync(dataPath);
    }

    for (let i = 0; i < allFamilies.length; i++) {
        let productFamily = allFamilies[i];

        let productFamilyPath = path.join(
            __dirname,
            "data",
            productFamily.familyName
        );

        if (!fs.existsSync(productFamilyPath)) {
            fs.mkdirSync(productFamilyPath);
        }

        // 遍历product
        for (let j = 0; j < productFamily.products.length; j++) {
            let productPackages = productFamily.products[j].packages;

            let familyProductPath = path.join(
                productFamilyPath,
                productFamily.products[j].productName
            );

            for (let z = 0; z < productPackages.length; z++) {
                let pack = productPackages[z];

                // let packagePath = path.join(
                //     productFamilyPath,
                //     pack.monikerName
                // );

                try {
                    let namespaces = await getProductPackageNamespaces(pack);
                    // 保存到路径
                    if (!fs.existsSync(familyProductPath)) {
                        fs.mkdirSync(familyProductPath);
                    }

                    let packFilePath = path.join(
                        familyProductPath,
                        `${pack.monikerName}.json`
                    );

                    console.log("save to", packFilePath);
                    fs.writeFileSync(packFilePath, JSON.stringify(namespaces));
                } catch (error) {
                    console.error(error);
                    break;
                }
            }
        }
    }
};

main();
